home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 2 / Gold Medal Software Volume 2 (Gold Medal) (1994).iso / prog / asm_n_z.arj / NEWXDIR.ASM < prev    next >
Assembly Source File  |  1987-04-07  |  43KB  |  841 lines

  1. ;XDIR.COM for the IBM Personal Computer - 1986 by Jeff Prosise
  2. code          segment para public 'code'
  3.               assume cs:code
  4.               org 100h
  5. begin:        jmp initialize                ;goto initialization code
  6. ;
  7. copyright          db 'Copyright 1986 Ziff-Davis Publishing Co.',1Ah
  8. global             db '\*.*',0              ;global directory filespec
  9. dos_segment        dw ?                     ;DOS segment
  10. busy_flag          dw ?                     ;offset of DOS BUSY_FLAG
  11. program_status     db 0                     ;XDIR processing status
  12. flag_13h           db 0                     ;status of interrupt 13h
  13. request_flag       db 0                     ;status of processing request
  14. adapter            db 2                     ;0 = MDA, 1 = CGA, 2 = EGA
  15. video_segment      dw 0B800h                ;video segment address
  16. video_page         db ?                     ;current video page
  17. border_attr        db 4Fh                   ;window border attribute
  18. text_attr          db 0Fh                   ;window text attribute
  19. video_address      dw ?                     ;window start address
  20. cursor_mode        dw ?                     ;cursor shape
  21. cursor_pos         dw ?                     ;cursor position
  22. maxlen             db ?                     ;maximum input string length
  23. max_page           db ?                     ;number of highest directory page
  24. dir_page           db ?                     ;current directory page
  25. end_flag           db ?                     ;status of text write routines
  26. error_flag         db ?                     ;critical error status
  27. default_cursor     dw 0607h                 ;default cursor shape (color)
  28. addr_6845          dw ?                     ;CRT Controller base address
  29. search_attr        dw 0                     ;file search attribute
  30. ;
  31. path               dw 0                          ;pointer to pathname buffer
  32. dta                dw 64                         ;pointer to Disk Transfer Area
  33. screen_buffer      dw offset initialize          ;pointer to screen buffer
  34. text_buffer        dw offset initialize+1536     ;pointer to filename buffer
  35. ;
  36. keyboard_int       label dword              ;old interrupt 9 vector
  37. old9h              dw 2 dup (?)
  38. timer_int          label dword              ;old interrupt 1Ch vector
  39. old1ch             dw 2 dup (?)
  40. bdisk_int          label dword              ;old interrupt 13h vector
  41. old13h             dw 2 dup (?)
  42. bp_int             label dword              ;old interrupt 28h vector
  43. old28h             dw 2 dup (?)
  44. ;
  45. old_dta_segment    dw ?                     ;old DTA segment address
  46. old_dta_offset     dw ?                     ;old DTA offset address
  47. old24h_segment     dw ?                     ;old interrupt 24h routine segment
  48. old24h_offset      dw ?                     ;old interrupt 24h routine offset
  49. enable_values      db 2Ch,28h,2Dh,29h       ;values to enable CGA output
  50.                    db 2Ah,2Eh,1Eh
  51. errtext            db 'No Files Found',0
  52. ;
  53. ;------------------------------------------------------------------------------
  54. ;Execution comes here thru interrupt 9 every time a key is pressed or released.
  55. ;------------------------------------------------------------------------------
  56. keyboard      proc near
  57.               sti                           ;set interrupt enable flag
  58.               push ax                       ;save AX
  59.               in al,60h                     ;get scan code from keyboard
  60.               cmp al,52                     ;was the '.' key pressed?
  61.               jne kb2                       ;no, then exit to normal handler
  62.               mov ah,2                      ;check shift key status
  63.               int 16h
  64.               test al,8                     ;is the Alt key pressed?
  65.               je kb2                        ;no, then exit
  66.               call kb_reset                 ;reset keyboard, issue EOI
  67.               pop ax                        ;restore AX
  68.               cmp program_status,0          ;XDIR routine already active?
  69.               jne kb1                       ;yes, then don't set request flag
  70.               mov request_flag,1            ;set request flag
  71. kb1:          iret                          ;end interrupt routine
  72. kb2:          pop ax                        ;restore AX
  73.               jmp keyboard_int              ;goto original keyboard routine
  74. keyboard      endp
  75. ;
  76. ;------------------------------------------------------------------------------
  77. ;Interrupt 1Ch handling routine.
  78. ;This procedure will now be used to handle int 8 instead of int 1c
  79. ;------------------------------------------------------------------------------
  80. timer         proc near
  81.               pushf                         ;call original routine
  82.               call timer_int
  83.               cmp request_flag,0            ;request flag set?
  84.               je timer1                     ;no, then exit
  85.               push es                       ;save ES and DI
  86.               push di
  87.               mov es,dos_segment            ;get DOS segment in ES
  88.               mov di,busy_flag              ;address of DOS BUSY_FLAG in DI
  89.               cmp byte ptr es:[di],0        ;DOS service currently active?
  90.               pop di                        ;clean up the stack
  91.               pop es
  92.               jne timer1                    ;yes, then we must wait
  93.               cmp flag_13h,0                ;BIOS disk service active?
  94.               jne timer1                    ;yes, then don't interrupt it
  95.  
  96. test_8259_status:
  97.               push   AX                  ;Save altered registers
  98.               push   DX
  99.               mov    DX,20h              ;Port address of 8259 OCW3
  100.               mov    AL,03               ;Set the In-Service Reg. read
  101.                                          ;bits RR=1 and RIS=1
  102.               out    DX,AL               ;Tell 8259 to send ISR on next read
  103.               jmp    short get_mask      ;This causes a 7 clock delay period
  104.                                          ;on the AT to allow time for the 8259
  105.                                          ;to setup the ISR status for us     
  106. get_mask:
  107.               in     AL,DX               ;Get the ISR
  108.               or     AL,AL               ;Set zero flag if no interrupts are
  109.                                          ;being serviced
  110.               pop    DX                  ;Restore the altered registers
  111.               pop    AX
  112.  
  113.               jnz  timer1                ;A hard interrupt is in progress
  114.               mov request_flag,0            ;reset request flag
  115.               call directory                ;invoke directory routine
  116. timer1:       iret                          ;done - exit
  117. timer         endp
  118. ;------------------------------------------------------------------------------
  119. ;------------------------------------------------------------------------------
  120.  
  121.  
  122.  
  123. ;------------------------------------------------------------------------------
  124. ;Interrupt 13h handling routine.
  125. ;------------------------------------------------------------------------------
  126. bdisk         proc far
  127.               inc flag_13h         ;Set the busy flag
  128.               pushf                ;Simulate an interrupt call to the 
  129.               call bdisk_int       ;original disk interrupt routine
  130.               pushf                ;Save returned flags from disk interrupt
  131.               dec flag_13h         ;Clear the busy flag
  132.               popf                 ;Restore disk I/O status flags
  133.               ret 2                ;Far return and discard flags on the stack
  134. bdisk         endp
  135. ;
  136. ;------------------------------------------------------------------------------
  137. ;Interrupt 28h handling routine.
  138. ;------------------------------------------------------------------------------
  139. backproc      proc near
  140.               pushf                         ;call original routine
  141.               call bp_int
  142.               cmp request_flag,0            ;request flag clear?
  143.               je bp1                        ;yes, then exit
  144.               mov request_flag,0            ;clear request flag
  145.               call directory                ;execute directory routine
  146. bp1:          iret                          ;done - exit
  147. backproc      endp
  148. ;
  149. ;------------------------------------------------------------------------------
  150. ;Interrupt 24h handling routine.
  151. ;------------------------------------------------------------------------------
  152. ioerr         proc near
  153.               sti                           ;restore interrupts
  154.               mov error_flag,1              ;set external error flag
  155.               mov al,0                      ;tell DOS to ignore the error
  156.               iret                          ;give control back to DOS
  157. ioerr         endp
  158. ;
  159. ;------------------------------------------------------------------------------
  160. ;DIRECTORY is called by other routines to pop up and control the window.
  161. ;------------------------------------------------------------------------------
  162. directory     proc near
  163.               mov program_status,1          ;set program active flag
  164.               sti                           ;enable interrupts
  165.               push ax                       ;save registers
  166.               push bx
  167.               push cx
  168.               push dx
  169.               push si
  170.               push di
  171.               push ds
  172.               push es
  173.               push cs                       ;set DS to the code segment
  174.               pop ds
  175.               assume ds:code
  176.               push cs                       ;set ES to the code segment
  177.               pop es
  178. ;
  179. ;Make sure the current video mode is a text mode.
  180. ;
  181.               mov ah,15                     ;get video mode and page
  182.               int 10h
  183.               cmp al,2                      ;mode 2?
  184.               je dir1                       ;yes, then continue
  185.               cmp al,3                      ;mode 3?
  186.               je dir1                       ;yes, then continue
  187.               cmp al,7                      ;mode 7?
  188.               je dir1                       ;yes, then continue
  189. exit:         mov program_status,0          ;clear status flag
  190.               pop es                        ;restore registers and exit
  191.               pop ds
  192.               pop di
  193.               pop si
  194.               pop dx
  195.               pop cx
  196.               pop bx
  197.               pop ax
  198.               ret
  199. ;
  200. ;Save video parameters that must be used now or restored later.
  201. ;
  202. dir1:         mov video_page,bh             ;save current video page
  203.               mov ah,3                      ;get cursor mode
  204.               int 10h
  205.               mov cursor_mode,cx            ;save it
  206.               call cursor_address           ;get cursor address from CRTC
  207.               mov cursor_pos,ax             ;save it
  208.               cld                           ;clear DF for string operations
  209. ;
  210. ;Save the screen contents and open the directory window.
  211. ;
  212.               cmp adapter,1                 ;disable video if CGA installed
  213.               jne dir2
  214.               call disable_cga
  215. dir2:         call save_screen              ;save memory to be overwritten
  216.               call open_window              ;draw window to the display
  217.               cmp adapter,1                 ;re-enable CGA video
  218.               jne dir3
  219.               call enable_cga
  220. ;
  221. ;Set the DTA and interrupt 24h vector to areas inside XDIR.  Then get a
  222. ;directory path string from the keyboard.
  223. ;
  224. dir3:         call ioset                    ;set DTA and 24h vector
  225. dir4:         mov di,path                   ;point DI to directory path buffer
  226.               mov dx,020Ah                  ;specify input line location
  227.               mov cl,59                     ;specify max length of 59
  228.               call readln                   ;get path string from keyboard
  229.               cmp al,27                     ;was ESC pressed?
  230.               jne dir5                      ;no, then continue
  231.               jmp escape                    ;ESC was pressed - exit
  232. dir5:         push cx                       ;save character count
  233.               mov ah,1                      ;hide the cursor
  234.               mov ch,20h
  235.               int 10h
  236.               pop cx                        ;retrieve count
  237.               mov dx,offset global+1        ;point DX to '*.*' text
  238.               or cl,cl                      ;any characters entered?
  239.               je dir7                       ;yes, then skip ahead
  240.               cmp byte ptr [di-1],'\'       ;is last character a backslash?
  241.               jne dir6                      ;no, then append backslash to path
  242.               dec di                        ;decrement path string pointer
  243. dir6:         lea si,global                 ;append '\*.*' text to path
  244.               mov cx,5
  245.               rep movsb
  246.               mov dx,path                   ;point DX to path string
  247. ;
  248. ;Read filename information from the specified directory.
  249. ;
  250. dir7:         call get_dir                  ;read directory information
  251.               mov dir_page,0                ;initialize page number
  252.               or cx,cx                      ;any files found?
  253.               jne dir9                      ;yes, then continue
  254. ;
  255. ;No files were found - print message and return to input loop.
  256. ;
  257.               mov dx,0721h                  ;set cursor position
  258.               lea si,errtext                ;point SI to error message
  259.               call write_string             ;write error message
  260.               call getkey                   ;wait for a keypress
  261.               call clear_input_line         ;clear input line
  262.               call clear_window             ;then clear the window
  263.               jmp dir4                      ;loop back for another try
  264. ;
  265. ;One or more files were found.  Display them and look for keystrokes.
  266. ;
  267. dir9:         call write_dir                ;write one directory page
  268. dir10:        call getkey                   ;wait for a keypress
  269.               cmp al,0                      ;extended code entered?
  270.               je dir11                      ;yes, then branch to handler
  271.               cmp al,27                     ;ESC pressed?
  272.               jne dir10                     ;no, then ignore keypress
  273.               call clear_input_line         ;clear window and loop back
  274.               call clear_window
  275.               jmp dir4
  276. dir11:        cmp ah,81                     ;PgDn pressed?
  277.               jne dir12                     ;no, then continue testing
  278.               mov al,dir_page               ;last page displayed?
  279.               cmp al,max_page
  280.               je dir10                      ;yes, then ignore keypress
  281.               inc dir_page                  ;advance page number
  282.               call clear_window             ;clear window
  283.               jmp dir9                      ;go back and display new page
  284. dir12:        cmp ah,73                     ;PgUp pressed?
  285.               jne dir10                     ;no, then ignore keypress
  286.               cmp dir_page,0                ;first page displayed?
  287.               je dir10                      ;yes, then ignore keypress
  288.               dec dir_page                  ;update page indicator
  289.               call clear_window             ;clear window
  290.               jmp dir9                      ;loop back
  291. ;
  292. ;Reset the 24h vector and DTA address, close the window, and exit.
  293. ;
  294. escape:       call ioreset                  ;restore DTA and 24h vector
  295.               cmp adapter,1                 ;disable CGA video
  296.               jne esc1
  297.               call disable_cga
  298. esc1:         call restore_screen           ;restore screen contents
  299.               cmp adapter,1                 ;re-enable CGA video
  300.               jne esc2
  301.               call enable_cga
  302. esc2:         mov ah,2                      ;set cursor position
  303.               mov bh,video_page
  304.               mov dx,cursor_pos
  305.               int 10h
  306.               mov ah,1                      ;then unblank the cursor
  307.               mov cx,cursor_mode
  308.               int 10h
  309.               jmp exit                      ;exit
  310. directory     endp
  311. ;
  312. ;------------------------------------------------------------------------------
  313. ;SAVE_SCREEN saves the contents of the screen that underlie the window.
  314. ;------------------------------------------------------------------------------
  315. save_screen   proc near
  316.               mov dx,0208h                  ;first window row and column
  317.               mov bl,video_page             ;retrieve active video page
  318.               xor bh,bh                     ;byte to word in BX
  319.               call video_offset             ;determine video memory offset
  320.               mov video_address,di          ;save offset address
  321.               mov si,di                     ;transfer it to SI
  322.               push ds                       ;save DS
  323.               mov ds,video_segment          ;then set it to the video segment
  324.               assume ds:nothing
  325.               mov di,screen_buffer          ;point DI to storage buffer
  326.               mov cx,12                     ;12 lines to save
  327. save1:        push cx                       ;save line count
  328.               mov cx,64                     ;64 characters per line
  329.               rep movsw                     ;transfer one line to storage
  330.               pop cx                        ;retrieve line count
  331.               add si,32                     ;point SI to next video line
  332.               loop save1                    ;loop until all lines are saved
  333.               pop ds                        ;restore DS
  334.               assume ds:code
  335.               ret                           ;exit
  336. save_screen   endp
  337. ;
  338. ;------------------------------------------------------------------------------
  339. ;RESTORE_SCREEN restores the saved contents of video memory.
  340. ;------------------------------------------------------------------------------
  341. restore_screen proc near
  342.               push es                       ;save ES register value
  343.               mov di,video_address          ;point DI to starting video offset
  344.               mov es,video_segment          ;point ES to video memory
  345.               mov si,screen_buffer          ;point SI to storage buffer
  346.               mov cx,12                     ;12 lines to restore
  347. restore1:     push cx                       ;save line count
  348.               mov cx,64                     ;64 characters per line
  349.               rep movsw                     ;restore one line
  350.               pop cx                        ;retrieve line count
  351.               add di,32                     ;set DI to next video line
  352.               loop restore1                 ;loop until done
  353.               pop es                        ;restore ES
  354.               ret
  355. restore_screen endp
  356. ;
  357. ;------------------------------------------------------------------------------
  358. ;VIDEO_OFFSET calculates the offset address in video memory that corresponds
  359. ;to the indicated row, column, and video page.
  360. ;Entry:  DH,DL - row, column           | Exit:  DI - offset
  361. ;        BX    - video page            |
  362. ;------------------------------------------------------------------------------
  363. video_offset  proc near
  364.               mov al,160                    ;row * 160
  365.               mul dh
  366.               shl dl,1                      ;column * 2
  367.               xor dh,dh                     ;byte to word in DX
  368.               add ax,dx                     ;add the results
  369.               mov di,ax                     ;save result in DI
  370.               mov ax,1000h                  ;length of one video page
  371.               mul bx                        ;page * 1000h
  372.               add di,ax                     ;add result to DI
  373.               ret
  374. video_offset  endp
  375. ;
  376. ;------------------------------------------------------------------------------
  377. ;DISABLE_CGA and ENABLE_CGA disable and enable CGA video output.
  378. ;------------------------------------------------------------------------------
  379. disable_cga   proc near
  380.               mov dx,3DAh                   ;address of Status Register
  381. disable1:     in al,dx                      ;get status
  382.               test al,8                     ;vertical retrace active?
  383.               je disable1                   ;no, then wait
  384.               sub dx,2                      ;MSR address in DX
  385.               mov al,25h                    ;value to disable video
  386.               out dx,al                     ;disable video output
  387.               ret
  388. disable_cga   endp
  389. ;
  390. enable_cga    proc near
  391.               mov ah,15                     ;get video mode
  392.               int 10h
  393.               lea bx,enable_values          ;get value to enable display
  394.               xlat                          ;value in AL
  395.               mov dx,3D8h                   ;MSR address
  396.               out dx,al                     ;enable video output
  397.               ret
  398. enable_cga    endp
  399. ;
  400. ;------------------------------------------------------------------------------
  401. ;KB_RESET resets the keyboard and issues an EOI to the 8259 PIC.
  402. ;------------------------------------------------------------------------------
  403. kb_reset      proc near
  404.               in al,61h                     ;get current control value
  405.               mov ah,al                     ;save it in AH
  406.               or al,80h                     ;set the high bit
  407.               out 61h,al                    ;send it to the control port
  408.               mov al,ah                     ;recover original value
  409.               out 61h,al                    ;send it out
  410.               cli                           ;suspend interrupts
  411.               mov al,20h                    ;load EOI value
  412.               out 20h,al                    ;send it to the 8259
  413.               sti                           ;restore interrupts
  414.               ret
  415. kb_reset      endp
  416. ;
  417. ;------------------------------------------------------------------------------
  418. ;SHOW_CURSOR sets the cursor to its default state.
  419. ;------------------------------------------------------------------------------
  420. show_cursor   proc near
  421.               mov ah,1                      ;interrupt 10h service 1
  422.               mov cx,default_cursor         ;set scan line definition
  423.               int 10h                       ;set cursor shape
  424.               ret
  425. show_cursor   endp
  426. ;
  427. ;------------------------------------------------------------------------------
  428. ;CURSOR_ADDRESS reads the current cursor position from the video controller.
  429. ;------------------------------------------------------------------------------
  430. cursor_address proc near
  431.               mov dx,addr_6845              ;get CRTC Address Register port
  432.               mov al,14                     ;OUT register number
  433.               out dx,al
  434.               inc dx                        ;point DX to Data Register
  435.               in al,dx                      ;read high byte of cursor address
  436.               mov ah,al                     ;save it in AH
  437.               dec dx                        ;point DX back to Address Register
  438.               mov al,15                     ;OUT next register number
  439.               out dx,al
  440.               inc dx                        ;point DX to Data Register
  441.               in al,dx                      ;read low byte of address
  442.               and ax,07FFh                  ;strip 'page' bits from address
  443.               mov bl,80                     ;then divide by 80
  444.               div bl
  445.               xchg ah,al                    ;reverse bytes for proper form
  446.               ret
  447. cursor_address endp
  448. ;
  449. ;------------------------------------------------------------------------------
  450. ;GETKEY waits for a keypress and returns the keycode in AX.
  451. ;Exit:  AX - keycode
  452. ;------------------------------------------------------------------------------
  453. getkey        proc near
  454.               mov ah,1                      ;check keyboard buffer
  455.               int 16h
  456.               jne getkey1                   ;jump if buffer contains a keycode
  457.               int 28h                       ;no key pressed - issue int 28h
  458.               jmp getkey                    ;loop back to try again
  459. getkey1:      mov ah,0                      ;get keycode from buffer
  460.               int 16h
  461.               ret                           ;exit with keycode in AX
  462. getkey        endp
  463. ;
  464. ;------------------------------------------------------------------------------
  465. ;OPEN_WINDOW writes the blank directory window to display memory.
  466. ;------------------------------------------------------------------------------
  467. open_window   proc near
  468.               push es                       ;save ES
  469.               mov es,video_segment          ;set ES:DI to video memory
  470.               mov di,video_address
  471.               mov al,218                    ;write first character
  472.               mov ah,border_attr
  473.               stosw
  474.               mov cx,62                     ;then do the next 62
  475.               mov al,32
  476.               rep stosw
  477.               mov al,191                    ;finish the first line
  478.               stosw
  479.               add di,32                     ;set DI to start of next line
  480.               mov cx,10                     ;10 lines to do
  481. open1:        push cx                       ;save line counter
  482.               mov al,179                    ;write first character on line
  483.               mov ah,border_attr
  484.               push ax                       ;save character/attribute pair
  485.               stosw                         ;write them to video memory
  486.               mov cx,62                     ;write next 62 characters
  487.               mov al,32
  488.               mov ah,text_attr
  489.               rep stosw
  490.               pop ax                        ;retrieve saved word for final char
  491.               stosw                         ;finish the line
  492.               add di,32                     ;set DI to start of next line
  493.               pop cx                        ;retrieve line counter
  494.               loop open1                    ;loop until 10 lines are done
  495.               mov al,192                    ;first character of last line
  496.               stosw
  497.               mov cx,62                     ;write the next 62 characters
  498.               mov al,196
  499.               rep stosw
  500.               mov al,217                    ;finish the last line
  501.               stosw
  502.               pop es                        ;restore ES
  503.               ret
  504. open_window   endp
  505. ;
  506. ;------------------------------------------------------------------------------
  507. ;READLN accepts input of a string entered from the keyboard.
  508. ;Entry:  ES:DI - buffer address        | Exit: CL - string length
  509. ;        DH,DL - cursor start position |
  510. ;        CL    - max length accepted   |
  511. ;------------------------------------------------------------------------------
  512. readln        proc near
  513.               mov maxlen,cl                 ;save max length
  514.               mov ah,2                      ;set cursor to start position
  515.               mov bh,video_page
  516.               int 10h
  517.               call show_cursor              ;make sure cursor is visible
  518.               xor cl,cl                     ;initialize counter
  519. read1:        call getkey                   ;get a character
  520.               cmp al,13                     ;ENTER key?
  521.               je read_exit                  ;yes, then exit
  522.               cmp al,27                     ;ESC key?
  523.               je read_exit                  ;yes, then exit
  524.               cmp al,8                      ;backspace key?
  525.               je backspace                  ;yes, then do backspace function
  526.               cmp al,32                     ;ASCII 32 or greater?
  527.               jb read1                      ;no, then ignore it
  528.               cmp cl,maxlen                 ;room for another entry?
  529.               je read1                      ;no, then ignore it
  530.               push ax                       ;save character just entered
  531.               push cx                       ;save character count
  532.               mov ah,10                     ;print the character
  533.               mov cx,1
  534.               int 10h
  535.               inc dl                        ;advance the cursor
  536.               mov ah,2
  537.               int 10h
  538.               pop cx                        ;retrieve count
  539.               pop ax                        ;retrieve character
  540.               stosb                         ;deposit entry in buffer
  541.               inc cl                        ;update count
  542.               jmp read1                     ;go back for more
  543. backspace:    or cl,cl                      ;any characters to delete?
  544.               je read1                      ;no, then ignore keystroke
  545.               push cx                       ;save count
  546.               dec dl                        ;move cursor back one space
  547.               mov ah,2
  548.               int 10h
  549.               mov ah,10                     ;print a space character
  550.               mov al,32
  551.               mov cx,1
  552.               int 10h
  553.               pop cx                        ;retrieve count
  554.               dec cl                        ;decrement it
  555.               dec di                        ;decrement buffer pointer
  556.               jmp read1                     ;go back for more
  557. read_exit:    ret                           ;exit
  558. readln        endp
  559. ;
  560. ;------------------------------------------------------------------------------
  561. ;IOSET saves the current DTA address and interrupt 24h vector, then replaces
  562. ;them with pointers to XDIR routines.  IORESET restores the original values.
  563. ;------------------------------------------------------------------------------
  564. ioset         proc near
  565.               push es                       ;save ES
  566.               mov ah,2Fh                    ;get current DTA address
  567.               int 21h
  568.               mov old_dta_segment,es        ;save it
  569.               mov old_dta_offset,bx
  570.               mov ah,1Ah                    ;set new DTA address
  571.               mov dx,dta
  572.               int 21h
  573.               mov ah,35h                    ;get interrupt 24h vector
  574.               mov al,24h
  575.               int 21h
  576.               mov old24h_segment,es         ;save it
  577.               mov old24h_offset,bx
  578.               mov ah,25h                    ;then set it to IOERR routine
  579.               lea dx,ioerr
  580.               int 21h
  581.               pop es                        ;restore ES
  582.               ret
  583. ioset         endp
  584. ;
  585. ioreset       proc near
  586.               mov ah,25h                    ;restore interrupt 24h vector
  587.               mov al,24h
  588.               mov dx,old24h_offset
  589.               push ds
  590.               assume ds:nothing
  591.               mov ds,old24h_segment
  592.               int 21h
  593.               mov ah,1Ah                    ;restore original DTA address
  594.               mov dx,old_dta_offset
  595.               mov ds,old_dta_segment
  596.               int 21h
  597.               pop ds
  598.               assume ds:code
  599.               ret
  600. ioreset       endp
  601. ;
  602. ;------------------------------------------------------------------------------
  603. ;GET_DIR reads the specified directory and stores the ASCIIZ filename text.
  604. ;Entry:  DS:DX - pathname              | Exit:  CX - number of files
  605. ;------------------------------------------------------------------------------
  606. get_dir       proc near
  607.               mov error_flag,0              ;initialize critical error flag
  608.               mov ah,4Eh                    ;find first filename
  609.               mov cx,search_attr            ;set search attribute
  610.               int 21h                       ;initiate file search
  611.               mov cx,0                      ;zero CX in case no files found
  612.               jc getdir4                    ;done if no files found
  613.               cmp error_flag,0              ;critical error flag clear?
  614.               jne getdir4                   ;no, then exit immediately
  615.               inc cx                        ;initialize file count
  616.               mov di,text_buffer            ;set buffer address
  617.               call copy_filename            ;copy filename to buffer
  618. getdir1:      mov ah,4Fh                    ;continue file search
  619.               int 21h
  620.               jc getdir2                    ;done if nothing found
  621.               cmp error_flag,0              ;did a critical error occur?
  622.               jne getdir2                   ;yes, then exit
  623.               call copy_filename            ;copy next filename
  624.               inc cx                        ;update counter
  625.               cmp cx,360                    ;buffer full?
  626.               jne getdir1                   ;no, go back for more
  627. getdir2:      sub di,13                     ;go back to start of last filename
  628. getdir3:      inc di                        ;point DI to next byte
  629.               cmp byte ptr es:[di],0        ;is this a zero byte?
  630.               jne getdir3                   ;no, then advance to next byte
  631.               dec byte ptr es:[di]          ;mark end of text with a 255
  632.               mov ax,cx                     ;calculate number of pages
  633.               dec ax
  634.               mov bl,40
  635.               div bl
  636.               mov max_page,al               ;save highest page number
  637. getdir4:      ret
  638. get_dir       endp
  639. ;
  640. ;------------------------------------------------------------------------------
  641. ;COPY_FILENAME copies an ASCIIZ filename from the DTA to the indicated address.
  642. ;Entry:  ES:DI - destination address
  643. ;------------------------------------------------------------------------------
  644. copy_filename proc near
  645.               mov si,dta                    ;get DTA address
  646.               add si,30                     ;point SI to start of filename
  647.               push cx                       ;save CX
  648.               mov cx,13                     ;filename length is 13 bytes
  649.               rep movsb                     ;copy filename to storage
  650.               pop cx                        ;restore entry value of CX
  651.               ret
  652. copy_filename endp
  653. ;
  654. ;------------------------------------------------------------------------------
  655. ;WRITE_DIR writes one page of directory data to the directory window.
  656. ;------------------------------------------------------------------------------
  657. write_dir     proc near
  658.               mov end_flag,0                ;initialize END_FLAG
  659.               mov ax,520                    ;520 bytes per directory page
  660.               mov bl,dir_page               ;get page number in BL
  661.               xor bh,bh                     ;byte to word in BX
  662.               mul bx                        ;find offset into TEXT_BUFFER
  663.               mov si,ax                     ;transfer offset to SI
  664.               add si,text_buffer            ;complete address calculation
  665.               mov dx,030Ah                  ;specify starting cursor position
  666.               mov cx,10                     ;do 10 lines
  667. wdir4:        push cx                       ;save line counter
  668.               call write_line               ;write one line
  669.               inc dh                        ;set cursor to next line
  670.               mov dl,10
  671.               pop cx                        ;restore line count
  672.               cmp end_flag,0                ;END_FLAG set?
  673.               jne wdir5                     ;yes, then terminate
  674.               loop wdir4                    ;loop until all lines are done
  675. wdir5:        ret
  676. write_dir     endp
  677. ;
  678. ;------------------------------------------------------------------------------
  679. ;WRITE_LINE writes a single line of directory text to the display.
  680. ;Entry:  DH,DL - starting row and column
  681. ;------------------------------------------------------------------------------
  682. write_line    proc near
  683.               mov cx,4                      ;4 entries per line
  684. wline1:       push cx                       ;save counter
  685.               push si                       ;save text address
  686.               push dx                       ;save cursor address
  687.               call write_string             ;write one entry
  688.               pop dx                        ;retrieve cursor address
  689.               add dl,16                     ;set cursor to next field
  690.               pop si                        ;retrieve text address
  691.               add si,13                     ;set it for next write
  692.               pop cx                        ;retrieve count
  693.               cmp end_flag,0                ;END_FLAG set?
  694.               jne wline2                    ;yes, then exit
  695.               loop wline1                   ;loop until done
  696. wline2:       ret
  697. write_line    endp
  698. ;
  699. ;------------------------------------------------------------------------------
  700. ;WRITE_STRING writes an ASCIIZ string to the display.
  701. ;Entry:  DH,DL - starting row and column
  702. ;        DS:SI - string address
  703. ;------------------------------------------------------------------------------
  704. write_string  proc near
  705.               mov ah,2                      ;set cursor to start position
  706.               mov bh,video_page
  707.               int 10h
  708.               mov cx,1                      ;output one character at a time
  709. write1:       lodsb                         ;get a character
  710.               or al,al                      ;is it a zero?
  711.               je write3                     ;yes, then exit
  712.               cmp al,255                    ;is it 255?
  713.               je write2                     ;yes, then set END_FLAG and exit
  714.               mov ah,10                     ;print character
  715.               int 10h
  716.               mov ah,2                      ;advance cursor
  717.               inc dl
  718.               int 10h
  719.               jmp write1                    ;loop until done
  720. write2:       mov end_flag,1                ;set END_FLAG
  721. write3:       ret
  722. write_string  endp
  723. ;
  724. ;------------------------------------------------------------------------------
  725. ;CLEAR_WINDOW clears the contents of the directory window.
  726. ;------------------------------------------------------------------------------
  727. clear_window  proc near
  728.               mov ah,6                      ;clear window with BIOS routine
  729.               mov al,0                      ;specify clear function
  730.               mov cx,030Ah                  ;specify window coordinates
  731.               mov dx,0C45h
  732.               mov bh,text_attr              ;attribute to be used
  733.               int 10h
  734.               ret
  735. clear_window  endp
  736. ;
  737. ;------------------------------------------------------------------------------
  738. ;CLEAR_INPUT_LINE clears the window input line.
  739. ;------------------------------------------------------------------------------
  740. clear_input_line proc near
  741.               mov ah,2                      ;set cursor to start of input line
  742.               mov dx,020Ah
  743.               mov bh,video_page
  744.               int 10h
  745.               mov ah,10                     ;then write a string of spaces
  746.               mov al,32
  747.               mov cx,60
  748.               int 10h
  749.               ret
  750. clear_input_line endp
  751. ;
  752. ;------------------------------------------------------------------------------
  753. ;INITIALIZE prepares the program for residency.
  754. ;------------------------------------------------------------------------------
  755. initialize    proc near
  756. ;
  757. ;Determine what type of video adapter is installed.
  758. ;
  759.               mov ah,12h                    ;prepare for call to int 10h
  760.               mov bl,10h                    ;function - request EGA info
  761.               int 10h
  762.               cmp bl,10h                    ;BL=10h?
  763.               je init1                      ;yes, then no EGA installed
  764.               or bh,bh                      ;BH=0?
  765.               jne init2                     ;no, then it's a monochrome system
  766.               jmp init3
  767. init1:        dec adapter                   ;decrement ADAPTER value
  768.               mov ah,15                     ;get video mode
  769.               int 10h
  770.               cmp al,7                      ;is it mode 7?
  771.               jne init3                     ;no, then it's a color system
  772.               dec adapter                   ;set ADAPTER to 0
  773. ;
  774. ;Modify video parameter values for monochrome, then initialize the cursor.
  775. ;
  776. init2:        sub video_segment,800h        ;set VIDEO_SEGMENT for monochrome
  777.               mov border_attr,70h           ;change attributes for monochrome
  778.               mov text_attr,07h
  779.               mov default_cursor,0C0Dh      ;set monochrome cursor definition
  780. init3:        call show_cursor              ;set cursor to default mode
  781. ;
  782. ;Determine the port address of the CRT Controller and store it.
  783. ;
  784.               mov ax,40h                    ;point ES to BIOS data segment
  785.               mov es,ax
  786.               mov di,63h                    ;point DI to address word
  787.               mov dx,es:[di]                ;get CRTC address
  788.               mov addr_6845,dx              ;save it
  789. ;
  790. ;Get and save the address of the DOS BUSY_FLAG.
  791. ;
  792.               mov ah,34h                    ;function 34h
  793.               int 21h                       ;get address
  794.               mov dos_segment,es            ;save segment
  795.               mov busy_flag,bx              ;save offset
  796. ;
  797. ;Save and replace all required interrupt vectors.
  798. ;
  799.               mov ah,35h                    ;get interrupt 9 vector
  800.               mov al,9
  801.               int 21h
  802.               mov old9h,bx                  ;save it
  803.               mov old9h[2],es
  804.               mov ah,25h                    ;point it to KEYBOARD routine
  805.               lea dx,keyboard
  806.               int 21h
  807.               mov ah,35h                    ;get interrupt 1Ch vector
  808.           mov al,8 ;patched vh
  809.               int 21h
  810.               mov old1ch,bx                 ;save it
  811.               mov old1ch[2],es
  812.               mov ah,25h                    ;then point it to TIMER
  813.               lea dx,timer
  814.               int 21h
  815.               mov ah,35h                    ;get interrupt 13h vector
  816.               mov al,13h
  817.               int 21h
  818.               mov old13h,bx                 ;save it
  819.               mov old13h[2],es
  820.               mov ah,25h                    ;point it to BDISK
  821.               lea dx,bdisk
  822.               int 21h
  823.               mov ah,35h                    ;get interrupt 28h vector
  824.               mov al,28h
  825.               int 21h
  826.               mov old28h,bx                 ;save it
  827.               mov old28h[2],es
  828.               mov ah,25h                    ;point it to BACKPROC
  829.               lea dx,backproc
  830.               int 21h
  831. ;
  832. ;Terminate but remain resident in memory.
  833. ;
  834.               mov dx,offset initialize+6216 ;point DX to end of resident code
  835.               int 27h                       ;terminate-but-stay-resident
  836. initialize    endp
  837. ;
  838. code          ends
  839.               end begin
  840.  
  841.